package com.cloud.business.service.sys.impl;

import cn.hutool.core.util.ReUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cloud.business.dao.sys.*;
import com.cloud.business.entity.sys.*;
import com.cloud.business.model.commonvm.DataCheckFlag;
import com.cloud.business.model.commonvm.DataDropDown;
import com.cloud.business.model.commonvm.DeletePost;
import com.cloud.business.model.commonvm.ResultMsg;
import com.cloud.business.model.sys.sysuservm.*;
import com.cloud.business.service.sys.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author dh
 * @since 2020-03-21
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ISysUserService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysRoleUserMapper sysRoleUserMapper;

    @Resource
    private SysRoleMapper sysRoleMapper;

    @Resource
    private SysStructMapper sysStructMapper;

    @Resource
    private SysRegMapStructMapper sysRegMapStructMapper;

    @Resource
    private SysEnumDictionaryMapper sysEnumDictionaryMapper;

    //region 获取分页列表

    /**
     * 获取分页列表
     *
     * @param sysUserQueryModel
     * @param page
     * @param msg
     * @throws Exception
     */
    @Override
    public void getListByPage(SysUserQueryModel sysUserQueryModel, IPage<SysUserModel> page, ResultMsg msg) throws Exception {
        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.lambda().ne(sysUserQueryModel.getOperationId() != -1, SysUser::getObjectId, -1)
                .eq(sysUserQueryModel.getStructId() != null && sysUserQueryModel.getStructId() != 0, SysUser::getStructId, sysUserQueryModel.getStructId())
                .and(!StringUtils.isEmpty(sysUserQueryModel.getQueryStr()), qer -> {
                    qer.like(SysUser::getTrueName, sysUserQueryModel.getQueryStr())
                            .or().like(SysUser::getMobileNumber, sysUserQueryModel.getQueryStr())
                            .or().like(SysUser::getUserName, sysUserQueryModel.getQueryStr());
                })
                .orderByDesc(SysUser::getModificationTime);

        IPage<SysUser> iPage = new Page<>(page.getCurrent(), page.getSize());

        if (page.getSize() == 0) {
            List<SysUser> sysUserList = sysUserMapper.selectList(sysUserQueryWrapper);
            iPage.setRecords(sysUserList);
            page.setTotal(sysUserList.size());
        } else {
            sysUserMapper.selectPage(iPage, sysUserQueryWrapper);
            page.setTotal(iPage.getTotal());
        }

        if (iPage.getRecords().size() > 0) {

            //角色下的用户
            List<Integer> userIds = sysRoleUserMapper.getUserIdsByRoleId(sysUserQueryModel.getRoleId());
            List<SysUser> sysUserList = iPage.getRecords();
            List<SysUserModel> sysUserModelList = new ArrayList<>();
            sysUserList.forEach(item -> {
                SysUserModel sysUserModel = new SysUserModel();
                BeanUtils.copyProperties(item, sysUserModel);
                if (sysUserQueryModel.getRoleId() != null && sysUserQueryModel.getRoleId() != 0) {
                    sysUserModel.setCheckFlag(userIds.contains(item.getObjectId()));
                }

                //翻译
                List<String> nameList = sysRoleMapper.getroleNamesByUserId(item.getObjectId());
                String roleNames = org.apache.commons.lang.StringUtils.join(nameList, "|");
                sysUserModel.setRoleNames(roleNames);
                String structName = sysStructMapper.getName(item.getStructId());
                sysUserModel.setStructName(structName);
                String sex = "0".equals(item.getEnumSex()) ? "男" : "女";
                sysUserModel.setSex(sex);

                //用户下的角色
                List<Integer> roleIds = sysRoleUserMapper.getRoleIdsByUserId(item.getObjectId());
                List<DataCheckFlag> dataCheckFlagList = new ArrayList<>();
                roleIds.forEach(roleid -> {
                    DataCheckFlag dataCheckFlag = new DataCheckFlag() {{
                        setObjectId(roleid);
                        setCheckFlag(true);
                    }};
                    dataCheckFlagList.add(dataCheckFlag);
                });
                sysUserModel.setDataChecks(dataCheckFlagList);
                sysUserModelList.add(sysUserModel);
            });
            page.setRecords(sysUserModelList);
        }

        msg.setMsg("获取成功");
    }
    //endregion

    //region 创建

    /**
     * 创建
     *
     * @param sysUserModel
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer create(SysUserModel sysUserModel, ResultMsg msg) throws Exception {
        Date now = new Date();
        //校验手机号码格式
        if (!org.apache.commons.lang.StringUtils.isBlank(sysUserModel.getMobileNumber())) {
            Boolean isMatch = ReUtil.isMatch("^1[\\d]{10}", sysUserModel.getMobileNumber());
            if (!isMatch) {
                throw new Exception("手机号码为11位数字，请输入正确的电话");
            }
        }
        //校验用户名手机号
        if (!chenckUserNameAndPhone(sysUserModel.getUserName(), sysUserModel.getMobileNumber())) {
            throw new Exception("用户名/手机号重复");
        }
        if (sysUserModel.getStructId() == null || sysUserModel.getStructId() == 0) {
            throw new Exception("请选择部门");
        }

        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserModel, sysUser);
        sysUser.setCreateTime(now);
        sysUser.setModificationTime(now);

        int count = sysUserMapper.insert(sysUser);

        if (count > 0) {
            List<DataCheckFlag> dateCheckFlagList = sysUserModel.getDataChecks();
            if (dateCheckFlagList != null && dateCheckFlagList.size() > 0) {
                List<SysRoleUser> sysRoleUserAddList = new ArrayList<>();
                dateCheckFlagList.forEach(item -> {
                    SysRoleUser sysRoleUser = new SysRoleUser() {{
                        setCreateTime(now);
                        setModificationTime(now);
                        setCreateUserId(sysUserModel.getCreateUserId());
                        setModificationUserId(sysUserModel.getCreateUserId());
                        setUserId(sysUser.getObjectId());
                        setRoleId(item.getObjectId());
                    }};
                    sysRoleUserAddList.add(sysRoleUser);
                });
                //批量插入到数据库分配角色
                sysRoleUserMapper.insertBatch(sysRoleUserAddList);
            }
        }

        msg.setMsg("创建成功");
        return sysUser.getObjectId();
    }
    //endregion

    //region 更新

    /**
     * 更新
     *
     * @param sysUserModel
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer update(SysUserModel sysUserModel, ResultMsg msg) throws Exception {
        Date now = new Date();
        //校验手机号码格式
        if (!org.apache.commons.lang.StringUtils.isBlank(sysUserModel.getMobileNumber())) {
            Boolean isMatch = ReUtil.isMatch("^1[\\d]{10}", sysUserModel.getMobileNumber());
            if (!isMatch) {
                throw new Exception("手机号码为11位数字，请输入正确的电话");
            }
        }

        SysUser sysUser = new SysUser();
        BeanUtils.copyProperties(sysUserModel, sysUser);
        sysUser.setModificationTime(now);

        if (sysUserModel.getStructId() == null || sysUserModel.getStructId() == 0) {
            throw new Exception("请选择部门");
        }

        int count = sysUserMapper.updateById(sysUser);

        if (count > 0) {
            List<DataCheckFlag> dateCheckFlagList = sysUserModel.getDataChecks();
            if (dateCheckFlagList != null && dateCheckFlagList.size() > 0) {

                QueryWrapper<SysRoleUser> sysRoleUserQueryWrapper = new QueryWrapper<>();
                sysRoleUserQueryWrapper.lambda()
                        .eq(SysRoleUser::getUserId, sysUser.getObjectId());
                List<SysRoleUser> sysRoleUserList = sysRoleUserMapper.selectList(sysRoleUserQueryWrapper);
                List<Integer> roleIds = sysRoleUserList.stream().map(SysRoleUser::getRoleId).collect(Collectors.toList());
                List<SysRoleUser> sysRoleUserAddList = new ArrayList<>();
                List<Integer> removeUserIds = new ArrayList<>();
                for (DataCheckFlag item :
                        dateCheckFlagList) {
                    if (item.isCheckFlag() && !roleIds.contains(item.getObjectId())) {

                        SysRoleUser sysRoleUser = new SysRoleUser() {{
                            setCreateTime(now);
                            setModificationTime(now);
                            setCreateUserId(sysUserModel.getCreateUserId());
                            setModificationUserId(sysUserModel.getCreateUserId());
                            setUserId(sysUser.getObjectId());
                            setRoleId(item.getObjectId());
                        }};

                        sysRoleUserAddList.add(sysRoleUser);

                    } else if (!item.isCheckFlag() && roleIds.contains(item.getObjectId())) {
                        SysRoleUser sysRoleUser = sysRoleUserList.stream().filter(o -> o.getRoleId().equals(item.getObjectId()))
                                .findAny().orElse(null);
                        if (sysRoleUser != null) {
                            removeUserIds.add(sysRoleUser.getObjectId());
                        }
                    }
                }
                if (sysRoleUserAddList.size() > 0) {
                    //批量插入到数据库
                    sysRoleUserMapper.insertBatch(sysRoleUserAddList);
                }
                if (removeUserIds.size() > 0) {
                    sysRoleUserMapper.deleteBatchIds(removeUserIds);
                }
            }
        }
        msg.setMsg("更新成功");
        return sysUser.getObjectId();
    }
    //endregion

    //region 获取单条

    /**
     * 获取单条
     *
     * @param operationId
     * @param objectId
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public SysUser getById(Integer operationId, Integer objectId, ResultMsg msg) throws Exception {
        SysUser sysUser = sysUserMapper.selectById(objectId);
        msg.setMsg("获取成功");
        return sysUser;
    }
    //endregion

    //region 批量删除

    /**
     * 批量删除
     *
     * @param deletePost
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public int deleteByList(DeletePost deletePost, ResultMsg msg) throws Exception {
        msg.setMsg("删除成功");
        int count = sysUserMapper.deleteBatchIds(deletePost.getKeyValues());
        if (count <= 0) {
            throw new Exception("删除失败");
        }
        //删除关联角色
        QueryWrapper<SysRoleUser> sysRoleUserQueryWrapper = new QueryWrapper<>();
        sysRoleUserQueryWrapper.lambda().in(SysRoleUser::getUserId, deletePost.getKeyValues());
        sysRoleUserMapper.delete(sysRoleUserQueryWrapper);
        return count;
    }
    //endregion

    //region 登陆

    /**
     * 登陆
     *
     * @param loginPost
     * @return
     * @throws Exception
     */
    @Override
    public SysUserModel login(LoginPost loginPost, ResultMsg msg) throws Exception {
        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.lambda()
                .eq(SysUser::getPassword, loginPost.getPassword())
                .and(un -> un.eq(SysUser::getUserName, loginPost.getUserName())
                        .or()
                        .eq(SysUser::getMobileNumber, loginPost.getUserName()));

        SysUser sysUser = sysUserMapper.selectOne(sysUserQueryWrapper);

        if (sysUser == null) {
            throw new Exception("用户名或者密码不正确");
        }

        SysUserModel sysUserModel = new SysUserModel();
        BeanUtils.copyProperties(sysUser, sysUserModel);

        String roleCodes = sysRoleUserMapper.getRoleCodes(sysUser.getObjectId());

        sysUserModel.setRoleCodes(roleCodes);

        msg.setMsg("获取成功");
        return sysUserModel;
    }
    //endregion

    //region 更新密码

    /**
     * 更新密码
     *
     * @param updPwdPost
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public Integer updPassword(UpdPwdPost updPwdPost, ResultMsg msg) throws Exception {
        Date now = new Date();
        SysUser sysUser = sysUserMapper.selectById(updPwdPost.getObjectId());

        if (sysUser == null) {

            throw new Exception("用户不存在");
        }

        if (!sysUser.getPassword().equals(updPwdPost.getOldPassword())) {
            throw new Exception("旧密码错误");
        }

        sysUser.setModificationTime(now);
        sysUser.setModificationUserId(updPwdPost.getOperationId());
        sysUser.setPassword(updPwdPost.getNewPassword());

        int count = sysUserMapper.updateById(sysUser);
        if (count <= 0) {
            throw new Exception("更新错误");
        }

        msg.setMsg("更新成功");
        return sysUser.getObjectId();
    }
    //endregion

    //region 重置密码

    /**
     * 重置密码
     *
     * @param operationId
     * @param objectId
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public Integer resetPwd(Integer operationId, Integer objectId, ResultMsg msg) throws Exception {
        Date now = new Date();
        SysUser sysUser = sysUserMapper.selectById(objectId);
        if (sysUser == null) {
            throw new Exception("用户不存在");
        }
        sysUser.setModificationTime(now);
        sysUser.setModificationUserId(operationId);
        sysUser.setPassword("123456");
        int count = sysUserMapper.updateById(sysUser);
        if (count <= 0) {
            throw new Exception("重置密码错误");
        }
        msg.setMsg("重置密码成功");
        return sysUser.getObjectId();
    }
    //endregion

    //region 按照角色/类型获取用户

    /**
     * 按照角色/类型获取用户
     *
     * @param operationId
     * @param RoleCode
     * @param EnumType
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public List<SysUser> getListByEnumtype(Integer operationId, String RoleCode, String EnumType, ResultMsg msg) throws Exception {
        //region 弃用
//        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
//        sysUserQueryWrapper.lambda()
//                .eq(!StringUtils.isEmpty(EnumType), SysUser::getEnumType, EnumType);
//
//        List<SysUser> sysUserList = sysUserMapper.selectList(sysUserQueryWrapper);
//
//        if (!StringUtils.isEmpty(RoleCode)) {
//            //获取角色Id
//            String[] roleCodeList = RoleCode.split(",");
//            List<Integer> roleIds = new ArrayList<>();
//            QueryWrapper<SysRole> sysRoleQueryWrapper = new QueryWrapper<>();
//            sysRoleQueryWrapper.lambda()
//                    .select(SysRole::getObjectId)
//                    .in(SysRole::getCode, roleCodeList);
//            List<Object> roleIdsObj = sysRoleMapper.selectObjs(sysRoleQueryWrapper);
//            roleIdsObj.forEach(roleUser -> {
//                roleIds.add((Integer.parseInt(roleUser.toString())));
//            });
//
//            //获取角色下所有的用户Id
//            List<Integer> allUserList = new ArrayList<>();
//            QueryWrapper<SysRoleUser> sysRoleUserQueryWrapper = new QueryWrapper<>();
//            sysRoleUserQueryWrapper.lambda()
//                    .select(SysRoleUser::getUserId)
//                    .in(SysRoleUser::getRoleId, roleIds);
//            List<Object> userIdsObj = sysRoleUserMapper.selectObjs(sysRoleUserQueryWrapper);
//            userIdsObj.forEach(roleUser -> {
//                allUserList.add((Integer.parseInt(roleUser.toString())));
//            });
//            //获取用户
//            sysUserList = sysUserList.stream().filter(f -> allUserList.contains(f.getObjectId())).collect(Collectors.toList());
//
//        }
        //endregion

        List<SysUser> sysUserList = sysUserMapper.getListByEnumtype(EnumType, RoleCode);

        msg.setMsg("获取成功");
        return sysUserList;
    }
    //endregion

    //region 校验用户名手机号

    /**
     * 校验用户名手机号
     *
     * @param userName
     * @param mobileNumber
     * @return
     * @throws Exception
     */
    private Boolean chenckUserNameAndPhone(String userName, String mobileNumber) throws Exception {

        QueryWrapper<SysUser> sysUserQueryWrapper = new QueryWrapper<>();
        sysUserQueryWrapper.lambda()
                .eq(SysUser::getUserName, userName)
                .eq(SysUser::getMobileNumber, mobileNumber);

        SysUser sysUser = sysUserMapper.selectOne(sysUserQueryWrapper);

        return sysUser == null;
    }
    //endregion

    //region 根据角色code获取用户集合下拉

    /**
     * 根据角色code获取用户集合下拉
     *
     * @param operationId
     * @param roleCode
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public List<DataDropDown> getUsersByRoleCode(Integer operationId, String roleCode, ResultMsg msg) throws Exception {
        List<DataDropDown> users = sysUserMapper.getUsersByRoleCode(roleCode);
        msg.setMsg("获取成功");
        return users;
    }
    //endregion

    //region 打卡

    //    /**
    //     * 打卡
    //     *
    //     * @param punchInPost
    //     * @return
    //     * @throws Exception
    //     */
    //    @Override
    //    public Boolean punchIn(PunchInPost punchInPost, ResultMsg msg) throws Exception {
    //
    //        //获取班次 判断当前用户是否排班 排班获取排班信息  如果没有打卡 进行打卡
    //        Date now = new Date();
    //        String nowStr = DateUtil.format(now, "yyyy-MM-dd");
    //        punchInPost.setToday(nowStr);
    //
    //        Date amIn = DateUtil.parse(nowStr + " 08:00:00");
    //        Date amOut = DateUtil.parse(nowStr + " 12:00:00");
    //        Date pmIn = DateUtil.parse(nowStr + " 13:00:00");
    //        Date pmOut = DateUtil.parse(nowStr + " 18:00:00");
    //
    //        punchInPost.setToday(nowStr);
    //        SysSignRecord signRecord = sysSignRecordMapper.getSignInRecord(punchInPost);
    //        if (signRecord == null) {
    //            signRecord = new SysSignRecord() {{
    //                setCreateTime(new Date());
    //                setModificationTime(new Date());
    //                setCreateUserId(punchInPost.getOperationId());
    //                setUserId(punchInPost.getOperationId());
    //                if (!(now.before(amIn))) {
    //                    setSignInTimeAm(now);
    //                } else if (amIn.before(now) && !(now.before(amOut))) {
    //                    setSignInTimeAm(now);
    //                    setInAmFlag(true);
    //                } else if (now.after(amOut) && now.before(pmIn)) {
    //                    setSignInTimeAm(now);
    //                    setSignOutTimeAm(now);
    //                    setInAmFlag(true);
    //                    setOutAmFlag(true);
    //                }
    //
    //
    //                if (punchInPost.getEnumPunchType().equals("0")) {
    //                    //判断上下午
    //                    if (!(amIn.before(now)) && !(now.before(amOut))) {
    //                        //判断是否迟到早退
    //
    //
    //                        setSignInTimeAm(now);
    //                    }
    //                    //判断上下午
    //                    if (!(pmIn.before(now)) && !(now.before(pmOut))) {
    //                        setSignOutTimeAm(now);
    //                    }
    //                }
    //                if (punchInPost.getEnumPunchType().equals("1")) {
    //                    //判断上下午
    //                    if (!(amIn.before(now)) && !(now.before(amOut))) {
    //                        setSignInTimeAm(now);
    //                    }
    //                    //判断上下午
    //                    if (!(pmIn.before(now)) && !(now.before(pmOut))) {
    //                        setSignOutTimeAm(now);
    //                    }
    //                }
    //            }};
    //            sysSignRecordMapper.insert(signRecord);
    //        } else {
    //
    //            if (punchInPost.getEnumPunchType().equals("0")) {
    //                //判断上下午
    //                if (!(amIn.before(now)) && !(now.before(amOut))) {
    //                    setSignInTimeAm(now);
    //                }
    //                //判断上下午
    //                if (!(pmIn.before(now)) && !(now.before(pmOut))) {
    //                    setSignOutTimeAm(now);
    //                }
    //            }
    //            if (punchInPost.getEnumPunchType().equals("1")) {
    //                //判断上下午
    //                if (!(amIn.before(now)) && !(now.before(amOut))) {
    //                    setSignInTimeAm(now);
    //                }
    //                //判断上下午
    //                if (!(pmIn.before(now)) && !(now.before(pmOut))) {
    //                    setSignOutTimeAm(now);
    //                }
    //            }
    //        }
    //
    //
    //        msg.setMsg("获取成功");
    //        return sysUser;
    //    }
    //endregion

    //region 获取下拉列表

    /**
     * 获取下拉列表
     *
     * @param operationId
     * @param msg
     * @return
     * @throws Exception
     */
    @Override
    public List<DataDropDown> getDropDownList(Integer operationId, ResultMsg msg) throws Exception {
        List<DataDropDown> dataDropDownList = sysUserMapper.getDropDownList();
        msg.setMsg("获取成功");
        return dataDropDownList;
    }
    //endregion
}
